package mrusanov.player

import mrusanov.nation.Nation
import java.util.Date
import mrusanov.experience.Experienced
import mrusanov.staff.{Born, Contracted}
import math.BigDecimal.RoundingMode
import mrusanov.team.Team
import mrusanov.player.psychology.PlayerPsychology

object Player {
  val MIN_DAMAGE = 1
  val MIN_HP = 1

  def apply(name:String, talent:Talent, birthDay:Date, experience:Int, nation:Nation, playerType:PlayerType):Player = {
    val player = new Player(name, talent, birthDay, experience,nation, playerType)
    val psychology = PlayerPsychology.createRandomPsychology(player)
    player._psychology = psychology
    player
  }
}

class Player private(val name:String, talent:Talent, override val birthDay:Date, experience:Int, val nation:Nation,
             val playerType:PlayerType)
  extends Experienced(experience, talent) with Contracted with Born with PhysicalShape {

  var team:Option[Team] = None
  private var _psychology:PlayerPsychology = _
  def psychology = _psychology

  def club = team.map(_.club)

  def hp = scala.math.max(Player.MIN_HP, physicalShapeInfluence(playerType.hp(level)))
  def damage = scala.math.max(Player.MIN_DAMAGE, physicalShapeInfluence(playerType.damage(level)))

  def physicallyAtLevel:Int = {
    val hpStream = Stream.from(1).map(i => (i, playerType.hp(i)))
    hpStream.filter(_._2 >= hp)(0)._1
  }

  private[this] def physicalShapeInfluence(value:Int):Int = {
    val shape = physicalShape + psychology.relationshipShapeBonus
    ((value * shape) / PhysicalShape.MAX_PHYSICAL_SHAPE).setScale(0, RoundingMode.HALF_UP).toInt
  }
}
